#include "socket_runner_builder.h"

#include <sys/socket.h>
#include <arpa/inet.h>
#include <cerrno>
#include <cstring>

#include "logger.h"
#include "socket_runner.h"

int SocketRunnerBuilder::SetPort(int port)
{
    port_ = port;
    if (port <= 0) {
        return EINVAL;
    }
    return 0;
}

int SocketRunnerBuilder::SetRequestSize(int size)
{
    size_ = size;
    return 0;
}

std::shared_ptr<SocketRunner> SocketRunnerBuilder::Build()
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0) {
        LOGGER() << "socket failed: " << strerror(errno) << std::endl;
        return nullptr;
    }

    struct sockaddr_in addr = {
        .sin_family = AF_INET,
        .sin_port = htons(port_),
        .sin_addr = {
            .s_addr = htonl(INADDR_ANY),
        },
    };
    auto ret = bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr));
    if (ret < 0) {
        LOGGER() << "bind failed: " << strerror(errno) << std::endl;
        return nullptr;
    }

    ret = listen(fd, size_);
    if (ret < 0) {
        LOGGER() << "listen failed: " << strerror(errno) << std::endl;
        return nullptr;
    }
    return std::make_shared<SocketRunner>(fd);
}
